package impl

import (
	"context"
	"errors"
	compb "gitee.com/micro-services/protocol/common"
	pb "gitee.com/micro-services/protocol/hotel/server"
	"micro.hotel.server/do"
	"micro.hotel.server/models"
	"strings"
	"time"
)

const (
	Success = "success"
)

func CreateHotel(ctx context.Context, r *pb.CreateHotelReq) (*pb.CreateHotelRsp, error) {
	hotel := &models.VsHotel{
		HotelName:        r.HotelName,
		HotelTitle:       r.HotelTitle,
		Description:      r.Description,
		HotelPhone:       r.HotelPhone,
		HotelAddress:     r.HotelAddress,
		HotelImg:         r.HotelImg,
		DetailImg:        strings.Join(r.DetailImg, ","),
		Longitude:        r.Longitude,
		Latitude:         r.Latitude,
		AreaId:           r.AreaID,
		BusinessCircleId: r.BusinessCircleID,
		HotelType:        r.HotelType,
		Score:            r.Score,
		CreatedTime:      time.Now().Unix(),
		UpdatedTime:      time.Now().Unix(),
	}

	err := do.CreateHotel(hotel)
	if err != nil {
		return nil, err
	}

	return &pb.CreateHotelRsp{RetCode: 0, Msg: Success}, nil
}

func DeleteHotel(ctx context.Context, r *pb.DeleteHotelReq) (*pb.DeleteHotelRsp, error) {
	err := do.DeleteHotel(r.HotelID)
	if err != nil {
		return nil, err
	}
	return &pb.DeleteHotelRsp{
		RetCode: 0,
		Msg:     Success,
	}, nil
}

func UpdateHotel(ctx context.Context, r *pb.UpdateHotelReq) (*pb.UpdateHotelRsp, error) {
	hotel := &models.VsHotel{
		HotelId:     r.HotelID,
		HotelTitle:  r.HotelTitle,
		Description: r.Description,
		HotelPhone:  r.HotelPhone,
		HotelImg:    r.HotelImg,
		DetailImg:   strings.Join(r.DetailImg, ","),
		HotelType:   r.HotelType,
		UpdatedTime: time.Now().Unix(),
	}

	err := do.UpdateHotel(hotel)
	if err != nil {
		return nil, err
	}

	return &pb.UpdateHotelRsp{
		RetCode: 0,
		Msg:     Success,
	}, nil
}

func BatchHotelInfo(ctx context.Context, r *pb.BatchHotelInfoReq) ([]*compb.HotelInfo, error) {

	hotels, err := do.BatchHotelInfo(r.HotelID)
	if err != nil {
		return nil, err
	}

	areaMap, err := do.AreaListMap(ctx)
	if err != nil {
		return nil, err
	}
	circleMap, err := do.CircleMap(ctx)
	if err != nil {
		return nil, err
	}
	infos := make([]*compb.HotelInfo, 0)
	for _, v := range hotels {
		infos = append(infos, &compb.HotelInfo{
			HotelID:          v.HotelId,
			HotelName:        v.HotelName,
			HotelTitle:       v.HotelTitle,
			Description:      v.Description,
			HotelPhone:       v.HotelPhone,
			HotelAddress:     v.HotelAddress,
			HotelImg:         v.HotelImg,
			DetailImg:        strings.Split(v.DetailImg, ","),
			Longitude:        v.Longitude,
			Latitude:         v.Latitude,
			AreaID:           v.AreaId,
			Area:             areaMap[v.AreaId],
			BusinessCircleID: v.BusinessCircleId,
			BusinessCircle:   circleMap[v.BusinessCircleId],
			HotelType:        v.HotelType,
			Score:            v.Score,
		})
	}

	return infos, err
}

func SearchHotel(ctx context.Context, r *pb.SearchHotelReq) ([]*compb.HotelInfo, int64, error) {
	if r.Limit < 1 {
		return nil, 0, errors.New("参数错误")
	}

	params := &models.SearchParams{
		HotelName:        r.HotelName,
		HotelTitle:       r.HotelTitle,
		HotelPhone:       r.HotelPhone,
		HotelAddress:     r.HotelAddress,
		AreaID:           r.AreaID,
		BusinessCircleID: r.BusinessCircleID,
		HotelType:        r.HotelType,
		Score:            r.Score,
		Offset:           r.Offset,
		Limit:            r.Limit,
	}

	areaMap, err := do.AreaListMap(ctx)
	if err != nil {
		return nil, 0, err
	}
	circleMap, err := do.CircleMap(ctx)
	if err != nil {
		return nil, 0, err
	}

	hotels, count, err := do.SearchHotel(params)
	if err != nil {
		return nil, 0, err
	}

	infos := make([]*compb.HotelInfo, 0)
	for _, v := range hotels {
		infos = append(infos, &compb.HotelInfo{
			HotelID:          v.HotelId,
			HotelName:        v.HotelName,
			HotelTitle:       v.HotelTitle,
			Description:      v.Description,
			HotelPhone:       v.HotelPhone,
			HotelAddress:     v.HotelAddress,
			HotelImg:         v.DetailImg,
			DetailImg:        strings.Split(v.DetailImg, ","),
			Longitude:        v.Longitude,
			Latitude:         v.Latitude,
			AreaID:           v.AreaId,
			Area:             areaMap[v.AreaId],
			BusinessCircleID: v.BusinessCircleId,
			BusinessCircle:   circleMap[v.BusinessCircleId],
			HotelType:        v.HotelType,
			Score:            v.Score,
		})
	}

	return infos, count, nil
}

func Recommend(ctx context.Context, r *pb.RecommendReq) ([]*compb.HotelInfo, int64, error) {
	if r.UserLongitude < 1 || r.UserLatitude < 1 {
		return nil, 0, errors.New("参数错误")
	}

	areaMap, err := do.AreaListMap(ctx)
	if err != nil {
		return nil, 0, err
	}
	circleMap, err := do.CircleMap(ctx)
	if err != nil {
		return nil, 0, err
	}

	hotels, count, err := do.Recommend(r.UserLongitude, r.UserLatitude, r.Limit, r.Offset)
	if err != nil {
		return nil, 0, err
	}

	infos := make([]*compb.HotelInfo, 0)
	for _, v := range hotels {
		infos = append(infos, &compb.HotelInfo{
			HotelID:          v.HotelId,
			HotelName:        v.HotelName,
			HotelTitle:       v.HotelTitle,
			Description:      v.Description,
			HotelPhone:       v.HotelPhone,
			HotelAddress:     v.HotelAddress,
			HotelImg:         v.HotelImg,
			DetailImg:        strings.Split(v.DetailImg, ","),
			Longitude:        v.Longitude,
			Latitude:         v.Latitude,
			AreaID:           v.AreaId,
			Area:             areaMap[v.AreaId],
			BusinessCircleID: v.BusinessCircleId,
			BusinessCircle:   circleMap[v.BusinessCircleId],
			HotelType:        v.HotelType,
			Score:            v.Score,
		})
	}

	return infos, count, nil
}
